#ifndef KERNEL_P_H
#define KERNEL_P_H

#include <QtCore/QObject>
#include <QtCore/QSettings>
#include <QtCore/QFile>
#include <QtCore/QMutex>
#include <QtCore/QThread>
#include <QtSql/QSqlDatabase>
#include "dbmanager/database_manager.h"
#include "binaryrpc/binaryrpc_server.h"

namespace smsbilling {

class Kernel;

class KernelPrivate : public QObject {
  Q_OBJECT
public:
  KernelPrivate();

  ~KernelPrivate();

  enum RowState {
    NO_UPDATED,
    UPDATED,
    DELETED,
    ADDED
  };

  class Tariff {
  public:
    Tariff(int id, const QString &name, float cost, RowState state = ADDED) :
      id(id), name(name), cost(cost), state(state) {

    }

    int id;
    QString name;
    float cost;
    RowState state;
  };

  class Resource {
  public:
    Resource(int id,
             int tariff_id,
             const QString &name,
             float balance,
             bool postpaid = false,
             RowState state = ADDED) :
      id(id),
      tariff_id(tariff_id),
      name(name),
      balance(balance),
      postpaid(postpaid),
      state(state) {

    }

    int id;
    int tariff_id;
    QString name;
    float balance;
    bool postpaid;
    RowState state;
  };

protected:

  void timerEvent(QTimerEvent *);

private slots:

  void threadStarted();

  void stop();

  void initServerExecuted();

  void initTariffsExecuted();

  void initResourcesExecuted();

  void syncDatabaseExecuted();

  void newBillingSession(binaryrpc::Session *session);

  void openSession();

  void closeSession();

  void errorSession(const QString &error_string);

  void newMessageSession(binaryrpc::ServerMessage *message);

  void syncDatabase();

signals:

  void sigStop();

private:

  bool readConfig(QSettings *config);

  void setState(State state);

  void initServer();

  void initTariffs();

  void initResources();

  void checkState();

  Tariff *getTariff(int id) const;

  Resource *getResource(int id) const;

  float roundUp(float val, unsigned int digits) const;

  friend class Kernel;

  int server_id;

  QString host_ip;

  quint16 host_port;

  int sync_db_time;

  int sync_db_timer;

  smslog::LogLevel log_level;

  QString db_host;

  int db_port;

  QString db_name;

  QString db_uname;

  QString db_pass;

  int num_connect_db;

  int exec_query_timeout;

  QString last_error;

  binaryrpc::Server *billing_server;

  DatabaseManager *db_manager;

  QThread *thread;

  State state;

  QMutex mutex;

  QList<binaryrpc::Session *> sessions;

  QList<Tariff *> tariffs;

  QList<Resource *> resources;

  QList<SqlQuery *> queries;
};

} // namespace smsbilling

#endif // KERNEL_P_H
